--- ../tk4.1/generic/tkScrollbar.c	Fri Feb 16 22:32:13 1996
+++ tkScrollbar.c	Mon Jul  8 19:24:13 1996
@@ -14,6 +14,10 @@
  *
  * SCCS: @(#) tkScrollbar.c 1.79 96/02/15 18:52:40
  */
+/*
+ * TkSTEP modifications Copyright
+ * by Alfredo K. Kojima 
+ */ 
 
 #include "tkPort.h"
 #include "default.h"
@@ -59,7 +63,9 @@
     Tk_3DBorder activeBorder;	/* For drawing backgrounds when active (i.e.
 				 * when mouse is positioned over element). */
     XColor *troughColorPtr;	/* Color for drawing trough. */
-    GC troughGC;		/* For drawing trough. */
+    XColor *darkPtr;		/* Color for background stipple */    
+    GC troughGC;		/* For drawing trough's stippled part. */
+    GC troughBackGC;		/* For drawing trough */
     GC copyGC;			/* Used for copying from pixmap onto screen. */
     int relief;			/* Indicates whether window as a whole is
 				 * raised, sunken, or flat. */
@@ -70,6 +76,8 @@
 				/* Color for drawing traversal highlight
 				 * area when highlight is off. */
     XColor *highlightColorPtr;	/* Color for drawing traversal highlight. */
+    Pixmap stipple;		/* trough base pattern */
+    Pixmap bump;		/* bump in the slider */
     int inset;			/* Total width of all borders, including
 				 * traversal highlight and 3-D border.
 				 * Indicates how much interior stuff must
@@ -166,6 +174,7 @@
 #define NEW_STYLE_COMMANDS	2
 #define GOT_FOCUS		4
 
+#define RECONFIGURE		256
 /*
  * Minimum slider length, in pixels (designed to make sure that the slider
  * is always easy to grab with the mouse).
@@ -174,30 +183,43 @@
 #define MIN_SLIDER_LENGTH	5
 
 /*
+ * If you want to make Tk ignore attribute settings that may be violating
+ * NEXTSTEP(tm) styles leave DISABLE_FORCE_STEP undef'ed, otherwise define it
+ * somewhere
+ */
+#ifndef DISABLE_FORCE_STEP
+#  define DISABLE_CHANGE	TK_CONFIG_DONT_CHANGE_DEFAULT
+#else
+#  define DISABLE_CHANGE	0
+#endif
+
+/*
  * Information used for argv parsing.
  */
 
 static Tk_ConfigSpec configSpecs[] = {
     {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
 	DEF_SCROLLBAR_ACTIVE_BG_COLOR, Tk_Offset(Scrollbar, activeBorder),
-	TK_CONFIG_COLOR_ONLY},
+	TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_BORDER, "-activebackground", "activeBackground", "Foreground",
 	DEF_SCROLLBAR_ACTIVE_BG_MONO, Tk_Offset(Scrollbar, activeBorder),
-	TK_CONFIG_MONO_ONLY},
+	TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_RELIEF, "-activerelief", "activeRelief", "Relief",
-	DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(Scrollbar, activeRelief), 0},
+	DEF_SCROLLBAR_ACTIVE_RELIEF, Tk_Offset(Scrollbar, activeRelief), 
+        0},
     {TK_CONFIG_BORDER, "-background", "background", "Background",
 	DEF_SCROLLBAR_BG_COLOR, Tk_Offset(Scrollbar, bgBorder),
-	TK_CONFIG_COLOR_ONLY},
+	TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_BORDER, "-background", "background", "Background",
 	DEF_SCROLLBAR_BG_MONO, Tk_Offset(Scrollbar, bgBorder),
-	TK_CONFIG_MONO_ONLY},
+	TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
 	(char *) NULL, 0, 0},
     {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
 	(char *) NULL, 0, 0},
     {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
-	DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(Scrollbar, borderWidth), 0},
+	DEF_SCROLLBAR_BORDER_WIDTH, Tk_Offset(Scrollbar, borderWidth), 
+        DISABLE_CHANGE},
     {TK_CONFIG_STRING, "-command", "command", "Command",
 	DEF_SCROLLBAR_COMMAND, Tk_Offset(Scrollbar, command),
 	TK_CONFIG_NULL_OK},
@@ -208,19 +230,23 @@
 	Tk_Offset(Scrollbar, elementBorderWidth), 0},
     {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
 	"HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
-	Tk_Offset(Scrollbar, highlightBgColorPtr), 0},
+	Tk_Offset(Scrollbar, highlightBgColorPtr), 
+        DISABLE_CHANGE},
     {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
 	DEF_SCROLLBAR_HIGHLIGHT,
-	Tk_Offset(Scrollbar, highlightColorPtr), 0},
+	Tk_Offset(Scrollbar, highlightColorPtr), 
+        DISABLE_CHANGE},
     {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
 	"HighlightThickness",
-	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(Scrollbar, highlightWidth), 0},
+	DEF_SCROLLBAR_HIGHLIGHT_WIDTH, Tk_Offset(Scrollbar, highlightWidth), 
+        DISABLE_CHANGE},
     {TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
 	DEF_SCROLLBAR_JUMP, Tk_Offset(Scrollbar, jump), 0},
     {TK_CONFIG_UID, "-orient", "orient", "Orient",
 	DEF_SCROLLBAR_ORIENT, Tk_Offset(Scrollbar, orientUid), 0},
     {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
-	DEF_SCROLLBAR_RELIEF, Tk_Offset(Scrollbar, relief), 0},
+	DEF_SCROLLBAR_RELIEF, Tk_Offset(Scrollbar, relief), 
+        DISABLE_CHANGE},
     {TK_CONFIG_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
 	DEF_SCROLLBAR_REPEAT_DELAY, Tk_Offset(Scrollbar, repeatDelay), 0},
     {TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
@@ -230,16 +256,35 @@
 	TK_CONFIG_NULL_OK},
     {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
 	DEF_SCROLLBAR_TROUGH_COLOR, Tk_Offset(Scrollbar, troughColorPtr),
-	TK_CONFIG_COLOR_ONLY},
+	TK_CONFIG_COLOR_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
 	DEF_SCROLLBAR_TROUGH_MONO, Tk_Offset(Scrollbar, troughColorPtr),
-	TK_CONFIG_MONO_ONLY},
+	TK_CONFIG_MONO_ONLY|DISABLE_CHANGE},
     {TK_CONFIG_PIXELS, "-width", "width", "Width",
-	DEF_SCROLLBAR_WIDTH, Tk_Offset(Scrollbar, width), 0},
+	DEF_SCROLLBAR_WIDTH, Tk_Offset(Scrollbar, width), 
+        DISABLE_CHANGE},
     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
 	(char *) NULL, 0, 0}
 };
 
+
+ 
+#define SB_BUMP_WIDTH  6
+#define SB_BUMP_HEIGHT 6
+static char scrollbar_bump[] = {
+" dbbb "\
+"dbdddd"\
+"bdd   "\
+"bd  ww"\
+"bd www"\
+" d ww "
+};
+
+
+static unsigned char scrollbar_bump_bmp[] = {
+   0x1e, 0x21, 0x39, 0x35, 0x3d, 0x1e};
+
+
 /*
  * Forward declarations for procedures defined later in this file:
  */
@@ -261,6 +306,83 @@
 static int		ScrollbarWidgetCmd _ANSI_ARGS_((ClientData clientData,
 			    Tcl_Interp *, int argc, char **argv));
 
+
+/*
+ *--------------------------------------------------------
+ * PaintPixmap -
+ *    Dirty routine to draw pixmaps from char data
+ *    
+ * gotta find a better way to do this...
+ *--------------------------------------------------------
+ */
+static void PaintPixmap(clientData, d, data, width, height)
+    ClientData clientData;
+    Drawable d;
+    char *data;
+    int width, height;
+{
+    int x, y, ofs=0;
+    Scrollbar *scrollPtr = (Scrollbar *)clientData;
+    Display *display = scrollPtr->display;
+    GC lightGC, backGC, darkGC, dark2GC;
+
+
+    backGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
+			   TK_3D_FLAT_GC);
+    lightGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
+			  TK_3D_LIGHT_GC);
+    darkGC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
+			   TK_3D_DARK_GC);
+    dark2GC = Tk_3DBorderGC( scrollPtr->tkwin, scrollPtr->bgBorder, 
+			   TK_3D_DARK2_GC);
+    for(y = 0; y < height; y++) {
+	for(x = 0; x < width; x++) {
+	    switch (data[ofs++]) {
+	     case 'b': /* black */
+		XDrawPoint( scrollPtr->display, d, dark2GC, x, y);
+		break;
+	     case 'd': /* dark */
+		XDrawPoint( scrollPtr->display, d, darkGC, x, y);
+		break;
+	     case 'w': /* white */
+		XDrawPoint( scrollPtr->display, d, lightGC, x, y);
+		break;
+	     default:
+		XDrawPoint( scrollPtr->display, d, backGC, x, y);
+	    }
+	}
+    }
+}
+
+
+/*
+ *---------------------------------------------
+ *  
+ * MakePixmaps
+ *   Make pixmaps needed by scrollbar with 
+ * PaintPixmap
+ *
+ *---------------------------------------------
+ */
+static void MakePixmaps(clientData)
+    ClientData clientData;
+{
+    register Scrollbar *scrollPtr = (Scrollbar *) clientData;
+
+    if (Tk_Depth(scrollPtr->tkwin) > 1) {
+	scrollPtr->bump = Tk_GetPixmap( scrollPtr->display, 
+	    Tk_WindowId(scrollPtr->tkwin),
+	    SB_BUMP_WIDTH, SB_BUMP_HEIGHT, Tk_Depth(scrollPtr->tkwin) );
+	PaintPixmap(clientData, scrollPtr->bump, scrollbar_bump,
+		    SB_BUMP_WIDTH, SB_BUMP_HEIGHT);
+	
+    } else { /* monochrome display */
+	scrollPtr->bump = XCreateBitmapFromData( scrollPtr->display,
+		Tk_WindowId(scrollPtr->tkwin), scrollbar_bump_bmp,
+		SB_BUMP_WIDTH, SB_BUMP_HEIGHT);
+    }
+}
+
 /*
  *--------------------------------------------------------------
  *
@@ -326,6 +448,10 @@
     scrollPtr->bgBorder = NULL;
     scrollPtr->activeBorder = NULL;
     scrollPtr->troughColorPtr = NULL;
+    scrollPtr->darkPtr = NULL;
+    scrollPtr->troughBackGC = None;
+    scrollPtr->bump = None;
+    scrollPtr->stipple = None;	
     scrollPtr->troughGC = None;
     scrollPtr->copyGC = None;
     scrollPtr->relief = TK_RELIEF_FLAT;
@@ -442,6 +568,8 @@
 		(char *) scrollPtr, argv[2], 0);
     } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0)
 	    && (length >= 2)) {
+	/* make sure that fg colors will be changed */	
+	scrollPtr->flags|=RECONFIGURE;
 	if (argc == 2) {
 	    result = Tk_ConfigureInfo(interp, scrollPtr->tkwin, configSpecs,
 		    (char *) scrollPtr, (char *) NULL, 0);
@@ -676,6 +804,18 @@
     if (scrollPtr->copyGC != None) {
 	Tk_FreeGC(scrollPtr->display, scrollPtr->copyGC);
     }
+    if (scrollPtr->troughBackGC != None) {
+	Tk_FreeGC(scrollPtr->display, scrollPtr->troughBackGC);
+    }
+    if (scrollPtr->bump != None) {
+	Tk_FreePixmap(scrollPtr->display, scrollPtr->bump);
+    }
+    if (scrollPtr->stipple != None) {
+	Tk_FreeBitmap(scrollPtr->display, scrollPtr->stipple);
+    }    
+    if (scrollPtr->darkPtr != NULL) {
+	Tk_FreeColor(scrollPtr->darkPtr);
+    }    
     Tk_FreeOptions(configSpecs, (char *) scrollPtr, scrollPtr->display, 0);
     ckfree((char *) scrollPtr);
 }
@@ -700,7 +840,6 @@
  *
  *----------------------------------------------------------------------
  */
-
 static int
 ConfigureScrollbar(interp, scrollPtr, argc, argv, flags)
     Tcl_Interp *interp;			/* Used for error reporting. */
@@ -714,13 +853,16 @@
 {
     size_t length;
     XGCValues gcValues;
+    XColor newcolor;
     GC new;
 
+    if (Tk_StrictMotif(scrollPtr->tkwin)) {
+	flags|=TK_CONFIG_CHECK_MY_FLAG;
+    } 
     if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs,
 	    argc, argv, (char *) scrollPtr, flags) != TCL_OK) {
 	return TCL_ERROR;
     }
-
     /*
      * A few options need special processing, such as parsing the
      * orientation or setting the background from a 3-D border.
@@ -743,20 +885,57 @@
 	scrollPtr->commandSize = 0;
     }
 
-    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);
+    if (scrollPtr->stipple==None) {
+	scrollPtr->stipple = Tk_GetBitmap((Tcl_Interp *)NULL, scrollPtr->tkwin,
+		Tk_GetUid("gray50"));
+	if (scrollPtr->stipple == None) {
+	    panic("ScrollBar couldn't allocate bitmap for trough");
+	}
+    }
+    
+    Tk_SetBackgroundFromBorder(scrollPtr->tkwin, scrollPtr->bgBorder);    
+    /* alloc color for trough base stipple */
+    newcolor.red = (60 * (int) scrollPtr->troughColorPtr->red)/100;
+    newcolor.green =(60 * (int) scrollPtr->troughColorPtr->green)/100;
+    newcolor.blue = (60 * (int) scrollPtr->troughColorPtr->blue)/100;
+    
+    if (scrollPtr->darkPtr != NULL) {
+	Tk_FreeColor(scrollPtr->darkPtr);
+    }    
+    scrollPtr->darkPtr = Tk_GetColorByValue(scrollPtr->tkwin,
+	&newcolor);
+
+    gcValues.background = scrollPtr->troughColorPtr->pixel;
+    gcValues.foreground = scrollPtr->darkPtr->pixel;   
+    gcValues.stipple = scrollPtr->stipple;
+    gcValues.fill_style = FillOpaqueStippled;
 
-    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
-    new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
+    new = Tk_GetGC(scrollPtr->tkwin, GCForeground|GCBackground|GCStipple|
+	GCFillStyle, &gcValues);
     if (scrollPtr->troughGC != None) {
 	Tk_FreeGC(scrollPtr->display, scrollPtr->troughGC);
     }
     scrollPtr->troughGC = new;
+    gcValues.foreground = scrollPtr->troughColorPtr->pixel;
+    new = Tk_GetGC(scrollPtr->tkwin, GCForeground, &gcValues);
+    if (scrollPtr->troughBackGC != None) {
+	Tk_FreeGC(scrollPtr->display, scrollPtr->troughBackGC);
+    }
+    scrollPtr->troughBackGC = new;
+	
     if (scrollPtr->copyGC == None) {
 	gcValues.graphics_exposures = False;
 	scrollPtr->copyGC = Tk_GetGC(scrollPtr->tkwin, GCGraphicsExposures,
 	    &gcValues);
     }
 
+    if (Tk_IsMapped(scrollPtr->tkwin)&&(scrollPtr->flags & RECONFIGURE)) {
+	scrollPtr->flags &= ~RECONFIGURE;
+	if (scrollPtr->bump != None) {
+	    Tk_FreePixmap(scrollPtr->display, scrollPtr->bump);
+	}
+	MakePixmaps(scrollPtr);
+    }
     /*
      * Register the desired geometry for the window (leave enough space
      * for the two arrows plus a minimum-size slider, plus border around
@@ -766,8 +945,85 @@
 
     ComputeScrollbarGeometry(scrollPtr);
     EventuallyRedraw(scrollPtr);
+
     return TCL_OK;
 }
+
+#define ARROW_UP	0
+#define ARROW_DOWN	1
+#define ARROW_LEFT	2
+#define ARROW_RIGHT	3
+/*
+ * DrawArrow --
+ *   	Draws an antialiased arrow with direction dir and size w x h. 
+ *      It's coordinates are relative to the center of the arrow. 
+ */
+static void DrawArrow(scrollPtr, drawable, x, y, w, h, dir)
+    Scrollbar   *scrollPtr;
+    Drawable	drawable;
+    int 	x, y;	/* position relative to middle of arrow */
+    int 	w, h;
+    char	dir;
+{
+    int i, hw;
+    float d, s;
+    GC 	core, border;
+
+    core = Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK2_GC);
+    border = Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK_GC);
+
+    if (h<3) h=3;
+    if (w<3) w=3;
+    if (dir<2) { /* vertical */
+	hw = w/2;
+	d = ((float)w/2)/(float)h;
+	y -= h/2;	
+    } else {
+	hw = h/2;
+	d = ((float)h/2)/(float)w;
+	x -= w/2;
+    }    
+    s=0;
+    switch (dir) {
+     case ARROW_DOWN:
+	s=h*d+0.5;
+	d=-d;
+     case ARROW_UP:
+	for(i = 0; i < h; i++) {
+	    s += d;	
+	    XDrawLine(scrollPtr->display, drawable, core,
+		      (unsigned)(x-(int)(s-0.5)), y+i,
+		      (unsigned)(x+(int)(s-0.5)), y+i);
+	    /* anti-aliasing */	
+	    if ((int)(s+0.5)!=(int)s) {
+		XDrawPoint(scrollPtr->display, drawable, 
+			   border, (unsigned)(x+(int)s), y+i);
+		XDrawPoint(scrollPtr->display, drawable,
+			   border, (unsigned)(x-(int)s), y+i);
+	    }
+	}
+	break;
+     case ARROW_RIGHT:
+	s=h*d+0.5;
+	d=-d;
+     case ARROW_LEFT:
+	for(i = 0; i < h; i++) {
+	    s += d;	
+	    XDrawLine(scrollPtr->display, drawable,
+		      core, x+i,(unsigned)(y-(int)(s-0.5)),
+		      x+i,(unsigned)(y+(int)(s-0.5)));
+	    /* anti-aliasing */	
+	    if ((int)(s+0.5)!=(int)s) {
+		XDrawPoint(scrollPtr->display, drawable,
+			   border, x+i,(unsigned)(y+(int)s));
+		XDrawPoint(scrollPtr->display, drawable,
+			   border, x+i,(unsigned)(y-(int)s));
+	    }
+	}
+	break;
+    }
+}
+
 
 /*
  *--------------------------------------------------------------
@@ -793,15 +1049,21 @@
 {
     register Scrollbar *scrollPtr = (Scrollbar *) clientData;
     register Tk_Window tkwin = scrollPtr->tkwin;
-    XPoint points[7];
     Tk_3DBorder border;
-    int relief, width, elementBorderWidth;
+    int relief, width, elementBorderWidth, sliderSize, delta;
+    int arrowl = scrollPtr->arrowLength;
     Pixmap pixmap;
+    int empty=0;	
+
 
     if ((scrollPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
 	goto done;
     }
 
+    if ((scrollPtr->firstFraction<=0.0) && (scrollPtr->lastFraction>=1.0)) {
+	empty=1;
+    }
+    
     if (scrollPtr->vertical) {
 	width = Tk_Width(tkwin) - 2*scrollPtr->inset;
     } else {
@@ -812,6 +1074,10 @@
 	elementBorderWidth = scrollPtr->borderWidth;
     }
 
+    if (scrollPtr->bump == None) {
+	MakePixmaps((ClientData)scrollPtr);
+    }
+
     /*
      * In order to avoid screen flashes, this procedure redraws
      * the scrollbar in a pixmap, then copies the pixmap to the
@@ -822,6 +1088,7 @@
     pixmap = Tk_GetPixmap(scrollPtr->display, Tk_WindowId(tkwin),
 	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
 
+    sliderSize = scrollPtr->sliderLast - scrollPtr->sliderFirst + 1;
     if (scrollPtr->highlightWidth != 0) {
 	GC gc;
 
@@ -832,16 +1099,60 @@
 	}
 	Tk_DrawFocusHighlight(tkwin, gc, scrollPtr->highlightWidth, pixmap);
     }
-    Tk_Draw3DRectangle(tkwin, pixmap, scrollPtr->bgBorder,
+    /*
+     * Tk_Draw3DRectangle(tkwin, pixmap, scrollPtr->bgBorder,
 	    scrollPtr->highlightWidth, scrollPtr->highlightWidth,
 	    Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
 	    Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
 	    scrollPtr->borderWidth, scrollPtr->relief);
-    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
-	    scrollPtr->inset, scrollPtr->inset,
-	    (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
-	    (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
+     */
+    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughBackGC,
+	scrollPtr->highlightWidth, scrollPtr->highlightWidth,
+ 	Tk_Width(tkwin) - 2*scrollPtr->highlightWidth,
+  	Tk_Height(tkwin) - 2*scrollPtr->highlightWidth);
+    
+    XDrawRectangle(scrollPtr->display, pixmap, 
+	Tk_3DBorderGC(scrollPtr->tkwin,scrollPtr->bgBorder,TK_3D_DARK2_GC),
+ 	scrollPtr->highlightWidth, scrollPtr->highlightWidth,
+ 	Tk_Width(tkwin) - 2*scrollPtr->highlightWidth-1,
+ 	Tk_Height(tkwin) - 2*scrollPtr->highlightWidth-1);
 
+    if (scrollPtr->vertical) {
+	if (!empty) {
+	    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
+		   scrollPtr->inset, scrollPtr->inset,
+		   (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
+		   (unsigned) (Tk_Height(tkwin) + 1 -
+		   (scrollPtr->arrowLength + scrollPtr->inset)*2));
+	} else {
+	    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
+		   scrollPtr->inset, scrollPtr->inset,
+		   (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
+		   (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
+	}
+    } else {
+	if (!empty) {
+	    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
+		   scrollPtr->arrowLength * 2+2,
+		   scrollPtr->inset,
+		   (unsigned) (Tk_Width(tkwin) -
+		   (scrollPtr->arrowLength*2 + scrollPtr->inset*2)),
+		   (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
+	} else {
+	    XFillRectangle(scrollPtr->display, pixmap, scrollPtr->troughGC,
+		   scrollPtr->inset, scrollPtr->inset,
+		   (unsigned) (Tk_Width(tkwin) - 2*scrollPtr->inset),
+		   (unsigned) (Tk_Height(tkwin) - 2*scrollPtr->inset));
+	}
+    }
+    
+    /* 
+     * don't draw slider/arrows if everything is visible
+     */
+    if (empty) {
+	goto docopy;
+    }    
+    
     /*
      * Draw the top or left arrow.  The coordinates of the polygon
      * points probably seem odd, but they were carefully chosen with
@@ -849,33 +1160,42 @@
      * cause the arrows to just fill the narrow dimension of the
      * scrollbar and be properly centered.
      */
-
     if (scrollPtr->activeField == TOP_ARROW) {
 	border = scrollPtr->activeBorder;
 	relief = scrollPtr->activeField == TOP_ARROW ? scrollPtr->activeRelief
 		: TK_RELIEF_RAISED;
+	delta = (relief == TK_RELIEF_SUNKEN) ? scrollPtr->borderWidth/2+1 : 0;
     } else {
 	border = scrollPtr->bgBorder;
 	relief = TK_RELIEF_RAISED;
+	delta = 0;
     }
+    
     if (scrollPtr->vertical) {
-	points[0].x = scrollPtr->inset - 1;
-	points[0].y = scrollPtr->arrowLength + scrollPtr->inset - 1;
-	points[1].x = width + scrollPtr->inset;
-	points[1].y = points[0].y;
-	points[2].x = width/2 + scrollPtr->inset;
-	points[2].y = scrollPtr->inset - 1;
-	Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
+	Tk_Fill3DRectangle(tkwin, pixmap, border, scrollPtr->inset,
+	 	Tk_Height(tkwin) - scrollPtr->arrowLength*2,
+		scrollPtr->width, scrollPtr->width,
 		elementBorderWidth, relief);
+	if (width >= 5) {
+	    DrawArrow(scrollPtr, pixmap, scrollPtr->inset+arrowl/2+delta
+		      -(2-(arrowl&1)),
+		      Tk_Height(tkwin) - (2-(arrowl&1)) + scrollPtr->inset/2 -
+		      arrowl*2 + (arrowl-scrollPtr->inset)/2+delta,
+		      arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
+		      ARROW_UP);
+	}	
     } else {
-	points[0].x = scrollPtr->arrowLength + scrollPtr->inset - 1;
-	points[0].y = scrollPtr->inset - 1;
-	points[1].x = scrollPtr->inset;
-	points[1].y = width/2 + scrollPtr->inset;
-	points[2].x = points[0].x;
-	points[2].y = width + scrollPtr->inset;
-	Tk_Fill3DPolygon(tkwin, pixmap, border, points, 3,
+	Tk_Fill3DRectangle(tkwin, pixmap, border,
+	 	scrollPtr->inset, scrollPtr->inset,
+		scrollPtr->width, scrollPtr->width,
 		elementBorderWidth, relief);
+	if (width >= 5) {
+	    DrawArrow(scrollPtr, pixmap, 3*scrollPtr->inset/2 - (arrowl&1) +
+		      (arrowl-scrollPtr->inset)/2+delta,
+		      scrollPtr->inset+ arrowl/2-(arrowl&1)+delta,
+		      arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
+		      ARROW_LEFT);
+	}
     }
 
     /*
@@ -886,40 +1206,48 @@
 	border = scrollPtr->activeBorder;
 	relief = scrollPtr->activeField == BOTTOM_ARROW
 		? scrollPtr->activeRelief : TK_RELIEF_RAISED;
+	delta = (relief == TK_RELIEF_SUNKEN) ? scrollPtr->borderWidth/2+1 : 0;
     } else {
 	border = scrollPtr->bgBorder;
 	relief = TK_RELIEF_RAISED;
+	delta = 0;
     }
     if (scrollPtr->vertical) {
-	points[0].x = scrollPtr->inset;
-	points[0].y = Tk_Height(tkwin) - scrollPtr->arrowLength
-		- scrollPtr->inset + 1;
-	points[1].x = width/2 + scrollPtr->inset;
-	points[1].y = Tk_Height(tkwin) - scrollPtr->inset;
-	points[2].x = width + scrollPtr->inset;
-	points[2].y = points[0].y;
-	Tk_Fill3DPolygon(tkwin, pixmap, border,
-		points, 3, elementBorderWidth, relief);
+	Tk_Fill3DRectangle(tkwin, pixmap, border, scrollPtr->inset,
+	 	Tk_Height(tkwin) - scrollPtr->arrowLength,
+		scrollPtr->width, scrollPtr->width,
+		elementBorderWidth, relief);
+	if (width >= 5 ) {
+	    DrawArrow(scrollPtr, pixmap, scrollPtr->inset+arrowl/2-
+		      (2-(arrowl&1))+delta,
+		      scrollPtr->inset/2+Tk_Height(tkwin) - (1-(arrowl&1)) -
+		      arrowl + (arrowl-scrollPtr->inset)/2+delta,
+		      arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
+		      ARROW_DOWN);	    
+	}	
     } else {
-	points[0].x = Tk_Width(tkwin) - scrollPtr->arrowLength
-		- scrollPtr->inset + 1;
-	points[0].y = scrollPtr->inset - 1;
-	points[1].x = points[0].x;
-	points[1].y = width + scrollPtr->inset;
-	points[2].x = Tk_Width(tkwin) - scrollPtr->inset;
-	points[2].y = width/2 + scrollPtr->inset;
-	Tk_Fill3DPolygon(tkwin, pixmap, border,
-		points, 3, elementBorderWidth, relief);
+	Tk_Fill3DRectangle(tkwin, pixmap, border, 
+	 	scrollPtr->inset + scrollPtr->arrowLength,
+		scrollPtr->inset, scrollPtr->width, scrollPtr->width,
+		elementBorderWidth, relief);
+	if (width >= 5) {
+	    DrawArrow(scrollPtr, pixmap, 3*scrollPtr->inset/2+delta-
+		      (arrowl&1) + arrowl + (arrowl-scrollPtr->inset)/2,
+		      scrollPtr->inset+arrowl/2-(arrowl&1)+delta,
+		      arrowl-2*scrollPtr->inset-3, arrowl-2*scrollPtr->inset-3,
+		      ARROW_RIGHT);
+	}
     }
 
+
     /*
      * Display the slider.
      */
 
     if (scrollPtr->activeField == SLIDER) {
 	border = scrollPtr->activeBorder;
-	relief = scrollPtr->activeField == SLIDER ? scrollPtr->activeRelief
-		: TK_RELIEF_RAISED;
+	relief = /*scrollPtr->activeField == SLIDER ? scrollPtr->activeRelief
+		:*/ TK_RELIEF_RAISED;
     } else {
 	border = scrollPtr->bgBorder;
 	relief = TK_RELIEF_RAISED;
@@ -927,20 +1255,32 @@
     if (scrollPtr->vertical) {
 	Tk_Fill3DRectangle(tkwin, pixmap, border,
 		scrollPtr->inset, scrollPtr->sliderFirst,
-		width, scrollPtr->sliderLast - scrollPtr->sliderFirst,
+		width, sliderSize,
 		elementBorderWidth, relief);
+	if ((sliderSize > SB_BUMP_HEIGHT*2) && (width > SB_BUMP_WIDTH)) {
+	    XCopyArea(scrollPtr->display, scrollPtr->bump, pixmap,
+		scrollPtr->copyGC, 0, 0, SB_BUMP_WIDTH, SB_BUMP_HEIGHT,
+		scrollPtr->inset + (width - SB_BUMP_WIDTH)/2-1, 
+		scrollPtr->sliderFirst - 1  + (sliderSize - SB_BUMP_HEIGHT)/2);
+	}
     } else {
 	Tk_Fill3DRectangle(tkwin, pixmap, border,
 		scrollPtr->sliderFirst, scrollPtr->inset,
-		scrollPtr->sliderLast - scrollPtr->sliderFirst, width,
+		sliderSize-1, width,
 		elementBorderWidth, relief);
+	if ((sliderSize > SB_BUMP_HEIGHT*2) && (width > SB_BUMP_HEIGHT)) {
+	    XCopyArea(scrollPtr->display, scrollPtr->bump, pixmap,
+		scrollPtr->copyGC, 0, 0, SB_BUMP_WIDTH, SB_BUMP_HEIGHT,
+		scrollPtr->sliderFirst + (sliderSize - SB_BUMP_HEIGHT)/2-1, 
+		scrollPtr->inset - 1 + (width - SB_BUMP_WIDTH)/2);
+	}
     }
 
     /*
      * Copy the information from the off-screen pixmap onto the screen,
      * then delete the pixmap.
      */
-
+    docopy:
     XCopyArea(scrollPtr->display, pixmap, Tk_WindowId(tkwin),
 	    scrollPtr->copyGC, 0, 0, (unsigned) Tk_Width(tkwin),
 	    (unsigned) Tk_Height(tkwin), 0, 0);
@@ -1106,8 +1446,13 @@
     if (scrollPtr->sliderLast > fieldLength) {
 	scrollPtr->sliderLast = fieldLength;
     }
-    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
-    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;
+    if (scrollPtr->vertical) {	
+	scrollPtr->sliderFirst += scrollPtr->inset;
+	scrollPtr->sliderLast += scrollPtr->inset;
+    } else {
+	scrollPtr->sliderFirst += scrollPtr->arrowLength*2 + scrollPtr->inset;
+	scrollPtr->sliderLast += scrollPtr->arrowLength*2 +scrollPtr->inset;
+    }        
 
     /*
      * Register the desired geometry for the window (leave enough space
@@ -1177,20 +1522,35 @@
      * All of the calculations in this procedure mirror those in
      * DisplayScrollbar.  Be sure to keep the two consistent.
      */
-
-    if (y < (scrollPtr->inset + scrollPtr->arrowLength)) {
-	return TOP_ARROW;
-    }
-    if (y < scrollPtr->sliderFirst) {
-	return TOP_GAP;
-    }
-    if (y < scrollPtr->sliderLast) {
-	return SLIDER;
-    }
-    if (y >= (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
+    if (scrollPtr->vertical) {	
+	if (y < scrollPtr->sliderFirst) {
+	    return TOP_GAP;
+	}
+	if (y < scrollPtr->sliderLast) {	    
+	    return SLIDER;
+	}
+	if (y < (length - (scrollPtr->arrowLength*2 + scrollPtr->inset + 1))) {
+	    return BOTTOM_GAP;
+	}
+	if (y < (length - (scrollPtr->arrowLength + scrollPtr->inset))) {
+	    return TOP_ARROW;
+	}
 	return BOTTOM_ARROW;
+    } else {
+	if (y < (scrollPtr->arrowLength + scrollPtr->inset)) {
+	    return TOP_ARROW;
+	}
+	if (y < (scrollPtr->arrowLength*2 + scrollPtr->inset + 1)) {
+	    return BOTTOM_ARROW;
+	}
+	if (y < (scrollPtr->sliderFirst)) {
+	    return TOP_GAP;
+	}
+	if (y < (scrollPtr->sliderLast)) {
+	    return SLIDER;
+	}
+	return BOTTOM_GAP;
     }
-    return BOTTOM_GAP;
 }
 
 /*
